package com.vst.orm.dao.jpa;

import java.io.Serializable;
import java.util.List;

import com.vst.orm.dao.DAOUtil;
import com.vst.orm.search.ExampleOptions;
import com.vst.orm.search.Filter;
import com.vst.orm.search.ISearch;
import com.vst.orm.search.Search;
import com.vst.orm.search.SearchResult;

public class GenericDAOImpl<T, ID extends Serializable>
  extends JPABaseDAO
  implements GenericDAO<T, ID>
{
  protected Class<T> persistentClass = (Class)DAOUtil.getTypeArguments(GenericDAOImpl.class, getClass()).get(0);
  
  public int count(ISearch search)
  {
    if (search == null) {
      search = new Search();
    }
    return _count(this.persistentClass, search);
  }
  
  public T find(ID id)
  {
    return (T)_find(this.persistentClass, id);
  }
  
  public T[] find(ID... ids)
  {
    return _find(this.persistentClass, ids);
  }
  
  public List<T> findAll()
  {
    return _all(this.persistentClass);
  }
  
  public void flush()
  {
    _flush();
  }
  
  public T getReference(ID id)
  {
    return (T)_getReference(this.persistentClass, id);
  }
  
  public T[] getReferences(ID... ids)
  {
    return _getReferences(this.persistentClass, ids);
  }
  
  public boolean isAttached(T entity)
  {
    return _contains(entity);
  }
  
  public void refresh(T... entities)
  {
    _refresh(entities);
  }
  
  public boolean remove(T entity)
  {
    return _removeEntity(entity);
  }
  
  public void remove(T... entities)
  {
    _removeEntities((Object[])entities);
  }
  
  public boolean removeById(ID id)
  {
    return _removeById(this.persistentClass, id);
  }
  
  public void removeByIds(ID... ids)
  {
    _removeByIds(this.persistentClass, ids);
  }
  
  public T merge(T entity)
  {
    return (T)_merge(entity);
  }
  
  public T[] merge(T... entities)
  {
    return _merge(this.persistentClass, entities);
  }
  
  public void persist(T... entities)
  {
    _persist(entities);
  }
  
  public T save(T entity)
  {
    return (T)_persistOrMerge(entity);
  }
  
  public T[] save(T... entities)
  {
    return _persistOrMerge(this.persistentClass, entities);
  }
  
  public <RT> List<RT> search(ISearch search)
  {
    if (search == null) {
      return (List<RT>) findAll();
    }
    return _search(this.persistentClass, search);
  }
  
  public <RT> SearchResult<RT> searchAndCount(ISearch search)
  {
    if (search == null)
    {
      SearchResult<RT> result = new SearchResult();
      result.setResult((List<RT>) findAll());
      result.setTotalCount(result.getResult().size());
      return result;
    }
    return _searchAndCount(this.persistentClass, search);
  }
  
  public <RT> RT searchUnique(ISearch search)
  {
    return (RT)_searchUnique(this.persistentClass, search);
  }
  
  public Filter getFilterFromExample(T example)
  {
    return _getFilterFromExample(example);
  }
  
  public Filter getFilterFromExample(T example, ExampleOptions options)
  {
    return _getFilterFromExample(example, options);
  }
}

